package com.ndood.spider.tmall.processor;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.ndood.core.util.UrlStringUtil;
import com.ndood.spider.tmall.bean.TmallGoods;

import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Selectable;

/**
 * 方案一
 */
@Component
public class TmallPageProcessor implements PageProcessor {
	Logger logger = LoggerFactory.getLogger(getClass());

	@Override
	public Site getSite() {
		Site site = Site.me().setCharset("UTF-8").setCycleRetryTimes(3).setSleepTime(3 * 1000)
		.addHeader("Connection", "keep-alive").addHeader("Cache-Control", "max-age=0")
		.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0");
		return site;
	}

	@Override
	public void process(Page page) {
		logger.info(page.getJson().get());
		
		try {
			// Step1: 处理商品列表页
			/*if (page.getHtml().xpath("//*[@id='J_ShopSearchResult']").get()!=null) {
				processGoodsList(page);
				return;
			}*/
			System.out.println(page.getUrl());
			System.out.println(page.getHtml());
			// Step2: 处理商品详情页
			if (page.getHtml().xpath("//*[@id='J_DetailMeta']").get()!=null) {
				processGoodsDetail(page);
				return;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 处理商品列表页
	 * 
	 * @param page
	 * @throws Exception
	 */
	private void processGoodsList(Page page) throws Exception {
		logger.info(page.getHtml().xpath("//*[@id='J_ShopSearchResult']").get());

		// Step1: 如果是非叶子节点，则把分类添加到url队列中
		if (page.getHtml().xpath("//*[@id='J_ShopSearchResult']/div/form/div/div[@class='cateAttrs']/div")
				.get() != null) {
			List<Selectable> cats = page.getHtml()
					.xpath("//*[@id='J_ShopSearchResult']/div/form/div/div[@class='cateAttrs']/div/div[@class='attrValues']/ul/li")
					.nodes();
			for (int i = 0; i < cats.size(); i++) {
				Selectable cat = cats.get(i);
				String catUrl = cat.xpath("//*/a").links().get();
				page.addTargetRequest(catUrl);
			}
			return;
		}

		// Step2: 获取下一页url
		String nextPageUrl = page.getHtml()
				.xpath("//*[@id='J_ShopSearchResult']/div[@class='skin-box-bd']/div[@class='J_TItems']/div[@class='pagination']/a[@class='J_SearchAsync next']")
				.links().get();
		if (!StringUtils.isEmpty(nextPageUrl)) {
			page.addTargetRequest(nextPageUrl);
		}

		// Step3: 获取page里的商品信息
		List<Selectable> items = page.getHtml()
				.xpath("//*[@id='J_ShopSearchResult']/div[@class='skin-box-bd']/div[@class='J_TItems']/div/dl[@class='item']")
				.nodes();

		// Step4: 获取分类路径
		String catPath = "";
		String cat = "";
		List<Selectable> paths = page.getHtml()
				.xpath("//*[@id='J_ShopSearchResult']/div/div[@class='J_TCrumb']/div/div/div/ul/li/div").nodes();
		for (int i = 0; i < paths.size(); i++) {
			Selectable path = paths.get(i);
			String pathName = path.xpath("//*/a/text()").get();
			if (pathName == null) {
				continue;
			}
			if (i == paths.size() - 1) {
				cat = pathName;
				catPath = catPath + pathName;
				continue;
			}
			catPath = pathName + ",";
		}

		// Step5: 根据商品列表跳转
		for (int i = 0; i < items.size(); i++) {
			Selectable item = items.get(i);
			String url = item.xpath("//*/dt/a/@href").get();
			page.addTargetRequest(url + "&cat=" + URLEncoder.encode(cat, "UTF-8") + "&catPath="
					+ URLEncoder.encode(catPath, "UTF-8"));
		}
	}

	/**
	 * 处理商品详情页
	 * 
	 * @param page
	 * @param goods
	 * @throws Exception
	 */
	private void processGoodsDetail(Page page) throws Exception {
		logger.info(page.getHtml().xpath("//*[@id='J_DetailMeta']").get());

		// 获取商品url
		String url = page.getUrl().get();
		if (!url.contains("id")) {
			return;
		}
		TmallGoods goods = new TmallGoods();
		goods.setUrl(url);

		// 获取商品id
		Map<String, String> paramsMap = UrlStringUtil.getParamsMap(url);
		String id = paramsMap.get("id");
		goods.setId(id);

		// 获取店铺名称
		String shopName = page.getHtml().xpath("//*[@id='shopExtra']/div[@class='slogo']/a/strong/text()").get();
		goods.setShopName(shopName);

		// 获取商品名称
		String name = page.getHtml()
				.xpath("//*[@id='J_DetailMeta']/div[@class='tm-clear']/div[@class='tb-property']/div/div[@class='tb-detail-hd']/h1/text()")
				.get();
		name = name.replace("/", "_");
		goods.setName(name);

		// 获取商品价格 
		String price = page.getHtml().xpath("//*[@id='J_PromoPrice']/dd/div/span/text()").get();
		if(price==null){
			price = page.getHtml().xpath("//*[@id='J_PromoPrice']/dd/span/text()").get();
		}
		if(price==null){ 
			price = page.getHtml().xpath("//*[@id='J_StrPriceModBox']/dd/span/text()").get();
		}
		goods.setPrice(price);

		// 获取商品分类
		String cat = paramsMap.get("cat");
		if(cat!=null){
			goods.setCat(URLDecoder.decode(cat, "UTF-8"));
		}
		String catPath = paramsMap.get("catpath");
		if(catPath!=null){
			goods.setCatPath(URLDecoder.decode(catPath, "UTF-8"));
		}
		// 获取商品图片
		List<Selectable> goodsImgs = page.getHtml().xpath("//*[@id='J_UlThumb']/li/a").nodes();
		Map<String, String> imgUrls = new HashMap<String, String>();
		for (int i = 0; i < goodsImgs.size(); i++) {
			Selectable goodsImg = goodsImgs.get(i);
			String goodsImgUrl = goodsImg.xpath("//*/img/@src").get();
			goodsImgUrl = goodsImgUrl.replaceAll("_([0-9]+)x([a-z0-9]+).jpg", "");
			imgUrls.put(name + i, goodsImgUrl);
		}
		goods.setImgUrls(imgUrls);

		// 获取颜色
		List<Selectable> colorImgs = page.getHtml()
				.xpath("//*[@id='J_DetailMeta']/div[@class='tm-clear']/div[@class='tb-property']/div/div[@class='tb-key']/div/div/dl[@class='tm-img-prop']/dd/ul/li")
				.nodes();
		Map<String, String> colorUrls = new HashMap<String, String>();
		for (int i = 0; i < colorImgs.size(); i++) {
			Selectable colorImg = colorImgs.get(i);
			// 获取颜色连接
			String colorUrl = colorImg.xpath("//*/a/@style").get();
			colorUrl = colorUrl.replaceAll("background:url\\(", "")
					.replaceAll("\\)([\\s]{0,})center([\\s]{0,})no-repeat;([\\s]{0,})", "");
			colorUrl = colorUrl.replaceAll("_([0-9]+)x([a-z0-9]+).jpg", "");

			// 获取颜色描述字段
			String colorName = colorImg.xpath("//*/a/span/text()").get();
			colorUrls.put(colorName, colorUrl);
		}
		goods.setColorUrls(colorUrls);

		// 获取月销量和评价
		String salesCount = page.getHtml()
				.xpath("//*[@id='J_DetailMeta']/div[@class='tm-clear']/div[@class='tb-property']/div/ul/li[@class='tm-ind-sellCount']/div/span[2]/text()")
				.get();
		if(salesCount==null){
			salesCount = page.getHtml().xpath("//*[@id='J_WrtAmount']/span[@class='tb-wrt-guc']/em/text()").get();
		}
		String commentsCount = page.getHtml().xpath("//*[@id='J_ItemRates']/div/span[2]/text()").get();
		goods.setSalesCount(salesCount);
		goods.setCommentsCount(commentsCount);

		// 获取品牌
		String brand = page.getHtml().xpath("//*[@id='J_BrandAttr']/div/a/text()").get();
		goods.setBrand(brand);

		// 获取参数
		List<Selectable> params = page.getHtml().xpath("//*[@id='J_AttrUL']/li").nodes();
		for (int i = 0; i < params.size(); i++) {
			Selectable param = params.get(i);
			String line = param.xpath("//*/text()").get().replace("&nbsp;", " ");
			if(line.split(":").length< 2){
				String key = line.split("：")[0];
				String value = line.split("：")[1];
				goods.getParams().put(key, value);
			}else{
				String key = line.split(":")[0];
				String value = line.split(":")[1];
				goods.getParams().put(key, value);
			}
		}

		// 获取商品描述 
		List<Selectable> descImgs = page.getHtml().xpath("//*[@id='description']/div/p/img").nodes();
		if(descImgs==null||descImgs.size()==0){
			descImgs = page.getHtml().xpath("//*[@id='description']/div/table/tbody/tr/td/div/img").nodes();
		}
		if(descImgs==null||descImgs.size()==0){
			descImgs = page.getHtml().xpath("//*[@id='description']/div/img").nodes();
		}
		if(descImgs==null||descImgs.size()==0){
			descImgs = page.getHtml().xpath("//*[@id='description']/div/p/span/img").nodes();
		}
		Map<String, String> descUrls = new HashMap<String, String>();
		for (int i = 0; i < descImgs.size(); i++) {
			Selectable descImg = descImgs.get(i);
			String descUrl = descImg.xpath("//*/@src").get();
			descUrl = descUrl.replaceAll("_([0-9]+)x([a-z0-9]+).jpg", "").replaceAll("https:", "");
			descUrls.put("商品描述" + i, descUrl);
		}
		goods.setDescUrls(descUrls);

		// 存入內存
		page.putField("goods" + id, goods);
	}

}